package com.chen.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chen.dao.mapper.CoachMapper;
import com.chen.dao.mapper.CommentMapper;
import com.chen.dao.mapper.CourseMapper;
import com.chen.dao.pojo.Coach;
import com.chen.dao.pojo.Comment;
import com.chen.dao.pojo.Course;
import com.chen.dao.pojo.User;
import com.chen.service.CoachService;
import com.chen.service.UserService;
import com.chen.util.DateUtils;
import com.chen.util.FileUtils;
import com.chen.vo.CoachVo;
import com.chen.vo.CommentVo;
import com.chen.vo.Result;
import com.chen.vo.param.CoachParam;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Author:chenao
 * @DATE:2022/3/19 15:38
 */
@Service
public class CoachServiceImpl implements CoachService {

    @Autowired
    private CoachMapper coachMapper;
    @Autowired
    private FileUtils fileUtils;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private CourseMapper courseMapper;

    private final static String formatPattern="yyyy-MM-dd HH:mm:ss";

    @Override
    public Coach findCoachById(String id) {
        return coachMapper.selectById(id);
    }

    @Override
    public Result login(CoachParam param) {
        LambdaQueryWrapper<Coach> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Coach::getUsername, param.getUsername());
        wrapper.eq(Coach::getPassword, param.getPassword());
        Coach coach = coachMapper.selectOne(wrapper);
        if (coach != null) {
            return Result.success(coach);
        } else {
            return Result.fail(10001, "用户名或密码错误");
        }
    }

    @Override
    public Result uploadAvatar(MultipartFile file, Map<String, String> params) {
        Map<String, String> map = fileUtils.saveFile(file, "coach");
        Coach coach = new Coach();
        coach.setAvatar(map.get("imageUrl"));
        coach.setId(params.get("coachId"));
        coachMapper.updateById(coach);
        return Result.success(coachMapper.selectById(params.get("coachId")));

    }

    @Override
    public Result updateCoach(CoachParam param) {
        Coach coach = new Coach();
        BeanUtils.copyProperties(param,coach);
        coachMapper.updateById(coach);
        return Result.success("ok");
    }

    @Override
    public Result listCoach(CoachParam param) {
        LambdaQueryWrapper<Coach> wrapper = new LambdaQueryWrapper<>();
        if (Strings.isNotBlank(param.getName())){
            wrapper.like(Coach::getName,param.getName());
        }
        List<Coach> coaches = coachMapper.selectList(wrapper);
        List<CoachVo> coachVoList = new LinkedList<>();
        coaches.stream().forEach(item->{
            CoachVo coachVo = new CoachVo();
            BeanUtils.copyProperties(item,coachVo);
            coachVoList.add(coachVo);
        });
        return Result.success(coachVoList);
    }

    @Override
    public Result updateRate(CoachParam param) {
        Coach originCoach = findCoachById(param.getId());
        Double originGrade = originCoach.getGrade();
        Integer originNum = originCoach.getRateNum();
        if (originNum>0){
            originGrade=originGrade*originNum;
        }
        Integer rateNum = ++originNum;
        Coach coach = new Coach();
        //计算出新的评分
        Double grade = (originGrade + param.getGrade()) / rateNum;
        //限制小数位数
        DecimalFormat df = new DecimalFormat( "0.00");
        coach.setGrade(Double.valueOf(df.format(grade)));
        coach.setId(param.getId());
        coach.setRateNum(rateNum);
        coachMapper.updateById(coach);
        return Result.success("评价成功!");
    }

    @Override
    public Result publishComment(CoachParam param) {
        Comment comment = new Comment();

        String editTime = DateUtil.format(new Date(), formatPattern);
        comment.setEditTime(editTime);
        comment.setCoachId(param.getId());
        comment.setUserId(param.getUserId());
        comment.setContent(param.getContent());
        commentMapper.insert(comment);
        return Result.success("评论成功");
    }

    @Override
    public Result listComment(CoachParam param) {
        LambdaQueryWrapper<Comment> commentWrapper = new LambdaQueryWrapper<>();
        commentWrapper.eq(Comment::getCoachId,param.getId());
        List<Comment> comments = commentMapper.selectList(commentWrapper);
        List<CommentVo> commentVoList = new LinkedList<>();
        comments.stream().forEach(item->{
            CommentVo commentVo = new CommentVo();
            User user = userService.queryUserById(item.getUserId());
            commentVo.setId(item.getId());
            commentVo.setContent(item.getContent());
            commentVo.setAvatarUrl(user.getAvatarUrl());
            commentVo.setUserNickName(user.getNickName());
            commentVo.setEditTime(item.getEditTime());
            commentVoList.add(commentVo);
        });
        return Result.success(commentVoList);
    }

    @Override
    public Result coachRecord(CoachParam param) {
        //今日课程
        int todayNum=0;
        //待上课程
        int waitNum=0;
        //本月课程
        int monthNum=0;
        LambdaQueryWrapper<Course> courseWrapper = new LambdaQueryWrapper<>();
        courseWrapper.eq(Course::getCoachId,param.getId());
        List<Course> courses = courseMapper.selectList(courseWrapper);
        for (Course item : courses) {
            String startTime = item.getStartTime();
            String endTime = item.getEndTime();
            Date today = new Date();
            DateTime startDate = DateUtil.parse(startTime, formatPattern);
            DateTime endDate = DateUtil.parse(endTime, formatPattern);
            if (DateUtil.isSameDay(today,startDate)){
                todayNum++;
            }
            //本月，且课程结束时间再此时之前，就计为本月已上
            if (DateUtil.isSameMonth(today,startDate) && endDate.getTime()<today.getTime()){
                monthNum++;
            }
            //这里的规则为课程开始时间在此时之后，就计为待上
            if (startDate.getTime()>today.getTime()){
                waitNum++;
            }
        }
        CoachVo coachVo = new CoachVo();
        coachVo.setMonthNum(monthNum);
        coachVo.setTodayNum(todayNum);
        coachVo.setWaitNum(waitNum);
        return Result.success(coachVo);
    }

    @Override
    public Result coachRank(CoachParam param) {
        //此时由于需要用到函数count，但之前的LambdaQueryWrapper没查到怎么使用函数，那就用普通wrapper自行拼接
        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        String currentTime = DateUtil.format(new Date(), formatPattern);
        wrapper.select("coach_id,count(*) as total");
        wrapper.lt("end_time",currentTime);
        wrapper.groupBy("coach_id");
        wrapper.orderByDesc("total");
        //此处的SQL语句格式为:SELECT coach_id,COUNT(*) AS total FROM table WHERE (end_time < '2022-04-01 20:00:00') GROUP BY coach_id ORDER BY total DESC
        List<Map<String, Object>> maps = courseMapper.selectMaps(wrapper);
        List<CoachVo> coachVoList=new ArrayList<>();
        for (Map<String, Object> map : maps) {
            String id = (String) map.get("coach_id");
            Integer total = Integer.parseInt(String.valueOf(map.get("total")));
            Coach coach = findCoachById(id);
            CoachVo coachVo = new CoachVo();
            BeanUtils.copyProperties(coach,coachVo);
            coachVo.setRankNum(total);
            coachVoList.add(coachVo);
        }
        return Result.success(coachVoList);
    }
}
